package cn.b.sky.mes.em.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import cn.b.sky.mes.em.dao.ProductionResultsDao;
import cn.b.sky.mes.em.model.EquipmentDownTime;
import cn.b.sky.mes.em.model.ProductionResults;
import cn.b.sky.mes.em.model.condition.ProductionResultsCondition;
import cn.b.sky.mes.em.service.ProductionResultsService;
import cn.b.sky.i18n.utils.LocaleResourceBundle;
import cn.b.sky.user.SecurityContextUtil;

@Service("productionResultsService")
public class ProductionResultsServiceImpl implements ProductionResultsService {

  private static final Logger LOG = LoggerFactory.getLogger(ProductionResultsServiceImpl.class);

  @Resource
  ProductionResultsDao productionResultsDao;

  @Override
  public List<ProductionResults> selectProductionResultsForOee(ProductionResultsCondition productionResultsCondition) {
    List<ProductionResults> results = productionResultsDao.selectProductionResultsForOee(productionResultsCondition);
    for (ProductionResults pr : results) {
      // A:时间稼动率(可用率)=(计划作业时间-停机时间)/计划作业时间
      if (pr.getDownTime() != null) {
        double availableRate = (pr.getScheduledTime() - pr.getDownTime()) / (double) pr.getScheduledTime();
        pr.setAvailableRate(availableRate);
      } else {
        pr.setAvailableRate(1.0);
        pr.setDownTime(0L);
      }
      // P:性能稼动率(表现性)=（理论周期时间x生产量）/（计划作业时间-停机时间）
      if (pr.getCycleTime() != null && pr.getGoodParts() != null) {
        double qualityRate = ((pr.getCycleTime() / 60.0) * (pr.getGoodParts() + pr.getDefectiveParts()))
            / (pr.getScheduledTime() - pr.getDownTime());
        pr.setPerformanceRate(qualityRate);
      } else {
        //由于
        String warn = LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
            SecurityContextUtil.getLanguageCode(), "because.M");
        if (pr.getCycleTime() == null) {
          //设备周期时间
          warn += LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
              SecurityContextUtil.getLanguageCode(), "equipmentCycleTime.M");
        }
        if (pr.getGoodParts() == null) {
          //设备产量
          warn += " "
              + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                  SecurityContextUtil.getLanguageCode(), "EquipmentOutput.M");
        }
        //没有配置  表现性 无法计算
        warn += "\\n"
            + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                SecurityContextUtil.getLanguageCode(), "haveNotConfig.M")
            + ","
            + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                SecurityContextUtil.getLanguageCode(), "performanceRate.C")
            + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                SecurityContextUtil.getLanguageCode(), "canNotBeCalculated.M") + "!";
        pr.setPerformanceRateWarn(warn);
      }
      // Q:良品率=良品数/(良品数数+不良品数量)
      if (pr.getGoodParts() != null) {
        double performanceRate = pr.getGoodParts() / (double) (pr.getGoodParts() + pr.getDefectiveParts());
        pr.setQualityRate(performanceRate);
      } else {
        String warn = LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
            SecurityContextUtil.getLanguageCode(), "because.M")
            + " "
            + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                SecurityContextUtil.getLanguageCode(), "EquipmentOutput.M")
            + " "
            + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                SecurityContextUtil.getLanguageCode(), "haveNotConfig.M")
            + "\\n"
            + ","
            + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                SecurityContextUtil.getLanguageCode(), "qualityRate.C")
            + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                SecurityContextUtil.getLanguageCode(), "canNotBeCalculated.M") + "!";
        pr.setQualityRateWarn(warn);
      }
      // 设备综合效率OEE=时间稼动率 ×性能稼动率 ×良品率
      if (pr.getAvailableRate() != null && pr.getPerformanceRate() != null && pr.getQualityRate() != null) {
        double oee = pr.getAvailableRate() * pr.getPerformanceRate() * pr.getQualityRate();
        pr.setOee(oee);
      } else {
        pr.setOeeWarn(LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
            SecurityContextUtil.getLanguageCode(), "availableRate.C")
            + "、"
            + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                SecurityContextUtil.getLanguageCode(), "performanceRate.C")
            + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                SecurityContextUtil.getLanguageCode(), "and.M")
            + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                SecurityContextUtil.getLanguageCode(), "qualityRate.C")
            + "\\n"
            + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                SecurityContextUtil.getLanguageCode(), "canNotCalculatOee.M") + "!");
      }
      pr.setWarn(pr.getAvailableRateWarn() + pr.getQualityRateWarn() + pr.getPerformanceRateWarn());
    }
    // 升序排列 oee为空排最后
    Collections.sort(results);
    return results;
  }

  @Override
  public int selectProductionResultsForOeeCount(ProductionResultsCondition productionResultsCondition) {
    return productionResultsDao.selectProductionResultsForOeeCount(productionResultsCondition);
  }

  @Override
  public List<EquipmentDownTime> selectShutDownCauseForOee(ProductionResultsCondition productionResultsCondition) {
    List<EquipmentDownTime> results = productionResultsDao.selectShutDownCauseForOee(productionResultsCondition);

    if (results != null && results.size() > 10) {
      List<EquipmentDownTime> newResults = new ArrayList<EquipmentDownTime>();
      int count = 0;
      for (int i = 0; i < results.size(); i++) {

        if (i >= 9) {
          count += results.get(i).getCount();
        } else {
          newResults.add(results.get(i));
        }
      }
      EquipmentDownTime ed = new EquipmentDownTime();
      //其他
      ed.setShutDownCauseText(LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
          SecurityContextUtil.getLanguageCode(), "other.M"));
      ed.setCount(count);
      newResults.add(ed);
      return newResults;
    }
    return results;
  }

  @Override
  public List<EquipmentDownTime> selectShutDownListForOee(ProductionResultsCondition productionResultsCondition) {
    return productionResultsDao.selectShutDownListForOee(productionResultsCondition);
  }

  @Override
  public List<ProductionResults> selectProductionResultsForTrend(ProductionResultsCondition productionResultsCondition) {
    try {
      List<ProductionResults> results = productionResultsDao
          .selectProductionResultsForTrend(productionResultsCondition);
      for (ProductionResults pr : results) {
        // A:时间稼动率(可用率)=(计划作业时间-停机时间)/计划作业时间
        if (pr.getDownTime() != null) {
          double availableRate = (pr.getScheduledTime() - pr.getDownTime()) / (double) pr.getScheduledTime();
          pr.setAvailableRate(availableRate);
        } else {
          pr.setAvailableRate(1.0);
          pr.setDownTime(0L);
        }
        // P:性能稼动率(表现性)=（理论周期时间x生产量）/（计划作业时间-停机时间）
        if (pr.getCycleTime() != null && pr.getGoodParts() != null) {
          double qualityRate = ((pr.getCycleTime() / 60.0) * (pr.getGoodParts() + pr.getDefectiveParts()))
              / (pr.getScheduledTime() - pr.getDownTime());
          pr.setPerformanceRate(qualityRate);
        } else {
          //由于
          String warn = LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
              SecurityContextUtil.getLanguageCode(), "because.M");
          if (pr.getCycleTime() == null) {
            //设备周期时间
            warn += LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                SecurityContextUtil.getLanguageCode(), "equipmentCycleTime.M");
          }
          if (pr.getGoodParts() == null) {
            //设备产量
            warn += " "
                + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                    SecurityContextUtil.getLanguageCode(), "EquipmentOutput.M");
          }
          //没有配置  表现性 无法计算
          warn += "\\n"
              + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                  SecurityContextUtil.getLanguageCode(), "haveNotConfig.M")
              + ","
              + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                  SecurityContextUtil.getLanguageCode(), "performanceRate.C")
              + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                  SecurityContextUtil.getLanguageCode(), "canNotBeCalculated.M") + "!";
          pr.setPerformanceRateWarn(warn);
        }
        // Q:良品率=良品数/(良品数数+不良品数量)
        if (pr.getGoodParts() != null) {
          double performanceRate = pr.getGoodParts() / (double) (pr.getGoodParts() + pr.getDefectiveParts());
          pr.setQualityRate(performanceRate);
        } else {
          String warn = LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
              SecurityContextUtil.getLanguageCode(), "because.M")
              + " "
              + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                  SecurityContextUtil.getLanguageCode(), "EquipmentOutput.M")
              + " "
              + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                  SecurityContextUtil.getLanguageCode(), "haveNotConfig.M")
              + "\\n"
              + ","
              + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                  SecurityContextUtil.getLanguageCode(), "qualityRate.C")
              + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                  SecurityContextUtil.getLanguageCode(), "canNotBeCalculated.M") + "!";
          pr.setQualityRateWarn(warn);
        }
        // 设备综合效率OEE=时间稼动率 ×性能稼动率 ×良品率
        if (pr.getAvailableRate() != null && pr.getPerformanceRate() != null && pr.getQualityRate() != null) {
          double oee = pr.getAvailableRate() * pr.getPerformanceRate() * pr.getQualityRate();
          pr.setOee(oee);
        } else {
          pr.setOeeWarn(LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
              SecurityContextUtil.getLanguageCode(), "availableRate.C")
              + "、"
              + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                  SecurityContextUtil.getLanguageCode(), "performanceRate.C")
              + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                  SecurityContextUtil.getLanguageCode(), "and.M")
              + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                  SecurityContextUtil.getLanguageCode(), "qualityRate.C")
              + "\\n"
              + LocaleResourceBundle.getCommonResourceLabel(SecurityContextUtil.getSiteCode(),
                  SecurityContextUtil.getLanguageCode(), "canNotCalculatOee.M") + "!");
        }
        pr.setWarn(pr.getAvailableRateWarn() + pr.getQualityRateWarn() + pr.getPerformanceRateWarn());
      }
      return results;
    } catch (Exception e) {
      LOG.error("{}", e);
    }
    return null;
  }

}
